package srv

import (
	"fmt"
	ymlv1 "github.com/ghodss/yaml"
	"github.com/hashicorp/consul/api"
	"github.com/nacos-group/nacos-sdk-go/clients"
	"github.com/nacos-group/nacos-sdk-go/common/constant"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"goTong/app/order/srv/config"
	"goTong/app/pkg/options"
	gapp "goTong/gtong/app"
	"goTong/gtong/registry"
	"goTong/gtong/registry/consul"
	"goTong/pkg/app"
	"goTong/pkg/log"
)

func NewApp(basename string) *app.App {
	cfg := config.New()
	appl := app.NewApp("order",
		"gotong",
		app.WithOptions(cfg),
		app.WithRunFunc(run(cfg)),
		//app.WithNoConfig(), //设置不读取配置文件
	)
	return appl
}

func NewRegistrar(registry *options.RegistryOptions) registry.Registrar {
	c := api.DefaultConfig()
	c.Address = registry.Address
	c.Scheme = registry.Scheme
	cli, err := api.NewClient(c)
	if err != nil {
		panic(err)
	}
	r := consul.New(cli, consul.WithHealthCheck(true))
	return r
}

func NeworderApp(cfg *config.Config) (*gapp.App, error) {
	//初始化log
	log.Init(cfg.Log)
	defer log.Flush()

	//服务注册
	register := NewRegistrar(cfg.Registry)

	//生成rpc服务
	rpcServer, err := NewOrderRPCServer(cfg)
	if err != nil {
		return nil, err
	}

	return gapp.New(
		gapp.WithName(cfg.Server.Name),
		gapp.WithRPCServer(rpcServer),
		gapp.WithRegistrar(register),
	), nil
}
func InitConfigSrv(cfg *config.Config) {
	//从nacos中读取配置信息
	sc := []constant.ServerConfig{
		{
			IpAddr: cfg.NacosOptions.Host,
			Port:   cfg.NacosOptions.Port,
		},
	}

	cc := constant.ClientConfig{
		NamespaceId:         cfg.NacosOptions.Namespace, // 如果需要支持多namespace，我们可以场景多个client,它们有不同的NamespaceId
		TimeoutMs:           5000,
		NotLoadCacheAtStart: true,
		LogDir:              "tmp/nacos/log",
		CacheDir:            "tmp/nacos/cache",
		LogLevel:            "debug",
	}

	configClient, err := clients.CreateConfigClient(map[string]interface{}{
		"serverConfigs": sc,
		"clientConfig":  cc,
	})
	if err != nil {
		panic(err)
	}

	content, err := configClient.GetConfig(vo.ConfigParam{
		DataId: cfg.NacosOptions.DataId,
		Group:  cfg.NacosOptions.Group})

	if err != nil {
		panic(err)
	}
	//想要将一个json字符串转换成struct，需要去设置这个struct的tag
	err = ymlv1.Unmarshal([]byte(content), &cfg)
	//if err != nil {
	//	log.Errorf("读取nacos配置失败： %s", err.Error())
	//}
	log.Infof("读取nacos配置：\r\n%s", content)
	err = configClient.ListenConfig(vo.ConfigParam{
		DataId: cfg.NacosOptions.DataId,
		Group:  cfg.NacosOptions.Group,
		OnChange: func(namespace, group, dataId, data string) {
			fmt.Println("配置文件变化")
			fmt.Println("group:" + group + ", dataId:" + dataId)
			err = ymlv1.Unmarshal([]byte(data), &cfg)
			log.Infof("读取nacos配置：\r\n%s", data)
			//if err != nil {
			//	log.Errorf("读取nacos配置失败： %s", err.Error())
			//}
		},
	})
	//if !debug {
	//	//动态获取闲置端口
	//	port, err := utils.GetFreePort()
	//	if err != nil {
	//		panic(err)
	//	}
	//	global.ServerConfig.Port = port
	//}
}

func run(cfg *config.Config) app.RunFunc {
	return func(baseName string) error {
		//如果配置了nacos等配置中心
		if cfg.Server.EnableConfigSrv {
			InitConfigSrv(cfg)
		}
		orderApp, err := NeworderApp(cfg)
		if err != nil {
			return err
		}

		//启动
		if err := orderApp.Run(); err != nil {
			log.Errorf("run user app error: %s", err)
			return err
		}
		return nil
	}
}
